package com.lcf.user.es_transport;

import com.alibaba.fastjson.JSON;
import com.lcf.user.entity.Person;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.util.*;
import java.util.concurrent.ExecutionException;

/**
 * 官方文档地址
 * https://www.elastic.co/guide/en/elasticsearch/client/index.html
 */
@RestController
@RequestMapping("/es")
public class EsController {
    private static final Logger logger = LoggerFactory.getLogger(EsController.class);
    @Autowired
    private TransportClient client;

    /**
     * client初始化
     */
    //@PostConstruct
    public void init() {
        try {
            /**
             *新版本 on startup
             Deprecated in 7.0.0.
             The TransportClient is deprecated in favour of the Java High Level REST Client and will be removed in Elasticsearch 8.0.
             The migration guide describes all the steps needed to migrate.
             */
            System.setProperty("es.set.netty.runtime.available.processors", "false");
            Settings settings = Settings.builder()
                    .put("cluster.name", "es1").build();
            client = new PreBuiltTransportClient(settings)
                    //.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9200));
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        } catch (Exception e) {
            logger.error("es init failed!", e);
        }
    }

    //创建索引并添加文档
    @GetMapping("/index")
    public String index() throws Exception {
        Map<String, Object> json = new HashMap<>();
        json.put("user", "kimchy");
        json.put("postDate", new Date());
        json.put("message", "trying out Elasticsearch");

        json.put("user", "alice");
        json.put("postDate", new Date());
        json.put("message", "nothing");

        IndexResponse response = client.prepareIndex("twitter", "_doc", "1")
                .setSource(json, XContentType.JSON)
                .get();

        response.getId();
        // Index name
        String _index = response.getIndex();
        // Type name
        String _type = response.getType();
        // Document ID (generated or not)
        String _id = response.getId();
        // Version (if it's the first time you index this document, you will get: 1)
        long _version = response.getVersion();
        // status has stored current instance statement.
        RestStatus status = response.status();
        // on shutdown
        //client.close();

        return "_index= " + _index + ", _type= " + _type + ", _id= " + _id + ", status= " + status;
    }

    //查询文档
    @GetMapping("/get/{id}")
    public GetResponse get(@PathVariable("id") String id) throws Exception {
        GetResponse response = client.prepareGet("twitter", "_doc", id).get();
        return response;
    }

    //删除文档（根据文档id删除）
    @GetMapping("/delete/{id}")
    public DeleteResponse delete(@PathVariable String id) {
        DeleteResponse response = client.prepareDelete("twitter", "_doc", id).get();
        return response;
    }

    //删除文档(带查询条件)
    @GetMapping("/delete/{key}/{value}")
    public long deleteByQuery(@PathVariable String key, @PathVariable String value) {
        BulkByScrollResponse response =
                new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE)
                        .filter(QueryBuilders.matchQuery(key, value))
                        .source("twitter")
                        .get();
        long deleted = response.getDeleted();
        return deleted;
    }

    //修改文档
    @PostMapping("/update")
    public UpdateResponse update(@RequestBody Person person) throws ExecutionException, InterruptedException {
        UpdateRequest updateRequest = new UpdateRequest();

        updateRequest.index("person");
        updateRequest.type("_doc");
        updateRequest.id(person.getId());
        updateRequest.doc(JSON.toJSONString(person), XContentType.JSON);
        UpdateResponse updateResponse = client.update(updateRequest).get();
        return updateResponse;
    }

    @GetMapping("/index2/{id}")
    public IndexResponse index(@PathVariable String id) throws Exception {
        Map<String, Object> json = new HashMap<String, Object>();

        json.put("name", "alice");
        json.put("sex", 1);
        json.put("height", 173.7);
        json.put("age", "23");
        json.put("email", "111@qq.com");

        IndexResponse response = client.prepareIndex("person", "_doc", id)
                .setSource(json, XContentType.JSON)
                .get();
        return response;
    }

    /**
     * 获取多个index下的文档
     *
     * @param id
     * @return
     * @throws Exception
     */
    @GetMapping("/multiGet/{id}")
    public List<Map<String, Object>> multiGet(@PathVariable String id) throws Exception {
        MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
                .add("twitter", "_doc", id)
                .add("person", "_doc", id, "2")
                .get();

        List<Map<String, Object>> list = new ArrayList<>();
        for (MultiGetItemResponse itemResponse : multiGetItemResponses) {
            GetResponse response = itemResponse.getResponse();
            if (response.isExists()) {
                Map<String, Object> source = response.getSource();
                list.add(source);
            }
        }
        return list;
    }

    /**
     * 批量
     * @param list
     * @return
     */
    @PostMapping("/bulk")
    public BulkResponse bulk(@RequestBody List<Person> list) {
        BulkRequestBuilder bulkRequest = client.prepareBulk();

        for (Person person : list) {
            // either use client#prepare, or use Requests# to directly build index/delete requests
            bulkRequest.add(client.prepareIndex("person", "_doc", person.getId())
                    .setSource(JSON.toJSONString(person), XContentType.JSON)
            );
        }

        BulkResponse bulkResponse = bulkRequest.get();
        if (bulkResponse.hasFailures()) {
            // process failures by iterating through each bulk response item
        }
        return bulkResponse;
    }

}
